package com.thermofisher.dsc.amanda.common.util;


import com.thermofisher.dsc.amanda.common.CommonConstants;
import com.thermofisher.dsc.amanda.security.jwt.IJWTInfo;
import com.thermofisher.dsc.amanda.security.jwt.JWTInfo;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.List;
import org.joda.time.DateTime;

public class JWTHelper {


    /**
     *
     * @param jwtInfo
     * @param priKeyPath
     * @param expire
     * @return
     * @throws Exception
     */
    public static String generateToken(IJWTInfo jwtInfo, String priKeyPath, int expire)
        throws Exception {
        String compactJws = Jwts.builder()
            .setSubject(jwtInfo.getUsername())
            .claim(CommonConstants.JWT_KEY_USER_ID, jwtInfo.getId())
            .claim(CommonConstants.JWT_KEY_PERMISSIONS, jwtInfo.getPermissions())
            .setExpiration(DateTime.now().plusSeconds(expire).toDate())
            .signWith(SignatureAlgorithm.RS256, RsaKeyHelper.getPrivateKey(priKeyPath))
            .compact();
        return compactJws;
    }

    /**
     * encryption token
     */
    public static String generateToken(IJWTInfo jwtInfo, byte priKey[], int expire)
        throws Exception {
        String compactJws = Jwts.builder()
            .setSubject(jwtInfo.getUsername())
            .claim(CommonConstants.JWT_KEY_USER_ID, jwtInfo.getId())
            .claim(CommonConstants.JWT_KEY_PERMISSIONS, jwtInfo.getPermissions())
            .setExpiration(DateTime.now().plusSeconds(expire).toDate())
            .signWith(SignatureAlgorithm.RS256, RsaKeyHelper.getPrivateKey(priKey))
            .compact();
        return compactJws;
    }

    /**
     * public key parsetoken
     */
    public static Jws<Claims> parserToken(String token, String pubKeyPath) throws Exception {
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(RsaKeyHelper.getPublicKey(pubKeyPath))
            .parseClaimsJws(token);
        return claimsJws;
    }

    /**
     * public key parsetoken
     */
    public static Jws<Claims> parserToken(String token, byte[] pubKey) throws Exception {
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(RsaKeyHelper.getPublicKey(pubKey))
            .parseClaimsJws(token);
        return claimsJws;
    }

    /**
     * get user info in the token
     */
    public static IJWTInfo getInfoFromToken(String token, String pubKeyPath) throws Exception {
        Jws<Claims> claimsJws = parserToken(token, pubKeyPath);
        Claims body = claimsJws.getBody();
        return new JWTInfo(body.getSubject(),
            getObjectValue(body.get(CommonConstants.JWT_KEY_USER_ID)),
            getListValue(body.get(CommonConstants.JWT_KEY_PERMISSIONS)));
    }

    /**
     * get user info from token
     */
    public static IJWTInfo getInfoFromToken(String token, byte[] pubKey) throws Exception {
        Jws<Claims> claimsJws = parserToken(token, pubKey);
        Claims body = claimsJws.getBody();
        return new JWTInfo(body.getSubject(),
            getObjectValue(body.get(CommonConstants.JWT_KEY_USER_ID)),
            getListValue(body.get(CommonConstants.JWT_KEY_PERMISSIONS)));
    }

    public static String getObjectValue(Object obj) {
        return obj == null ? "" : obj.toString();
    }

    public static List<String> getListValue(Object obj){
        if (obj != null && obj instanceof List){
            return (List<String>)obj;
        }
        return null;
    }
}
